package h.c.z.designPattern.C01_FactoryPattern.AbstractFactory;

/**
 * **优化方案** [客户端]屌丝升级 有媳妇了-->有钱了，请厨师了 --> 升级土豪 请各系厨师
 * 
 * @author jinsicao
 *
 */
public class EatWithAbstractFactory02 {

	public static void main(String[] args) {

		// AbstractFactory02 af02 = new GuangzhouFactory02();
		// AbstractFactory02 af02 = new ShandongFactory02();

		// AbstractFactory02 af02 = FactoryProducer
		//		.getFactory("h.c.z.designPattern.C01_FactoryPattern.AbstractFactory.ShandongFactory02");
		AbstractFactory02 af02 = FactoryProducer
				.getFactory("h.c.z.designPattern.C01_FactoryPattern.AbstractFactory.GuangzhouFactory02");

		AbstractRedMeatProduct meatProduct = (AbstractRedMeatProduct) af02.createProduct(1);
		meatProduct.createProduct();
		AbstractSteamedFishProduct fishProduct = (AbstractSteamedFishProduct) af02.createProduct(2);
		fishProduct.createProduct();
	}

}

/**
 * 工厂建造者
 * 
 * @author jinsicao
 */
class FactoryProducer {

	public static AbstractFactory02 getFactory(String factoryClassName) {
		if (factoryClassName != null && factoryClassName.trim().length() > 0) {
			Class<?> clazz;
			try {
				clazz = Class.forName(factoryClassName);
				if (clazz != null) {
					return (AbstractFactory02) clazz.newInstance();
				}
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			} catch (InstantiationException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			}
		}
		return null;
	}
}

/**
 * 可扩展的抽象工厂的接口（优化）
 * 
 * @author jinsicao
 *
 */
interface AbstractFactory02 {

	/**
	 * 一个通用的创建产品对象的方法，为了简单，直接返回Object 也可以为所有被创建的产品定义一个公共的接口
	 * 
	 * @param type
	 *            具体创建的产品类型标识
	 * @return 创建出的产品对象
	 */
	public Object createProduct(int type);
}

/**
 * 鲁菜系列
 * 
 * @author jinsicao
 */
class ShandongFactory02 implements AbstractFactory02 {

	@Override
	public Object createProduct(int type) {
		Object retObj = null;
		// type 1--红烧肉；2--清蒸鱼
		if (type == 1) {
			retObj = new ShandongCuisineRedMeatProduct();
		} else if (type == 2) {
			retObj = new ShandongCuisineSteamedFishProduct();
		}
		return retObj;
	}

}

/**
 * 粤菜系列
 * 
 * @author jinsicao
 */
class GuangzhouFactory02 implements AbstractFactory02 {

	@Override
	public Object createProduct(int type) {
		Object retObj = null;
		// type 1--红烧肉；2--清蒸鱼
		if (type == 1) {
			retObj = new GuangzhouCuisineRedMeatProduct();
		} else if (type == 2) {
			retObj = new GuangzhouCuisineSteamedFishProduct();
		}
		return retObj;
	}

}